'use strict';

var fs = require('fs');
var path = require('path');
var bench = require('./bench');
var show = require('./show');

var rc = 0;

process.on('uncaughtException', function(err) {
    console.log(err.stack);
    rc = 1;
});

process.on('exit', function () {
    process.exit(rc);
});

function interpretCmdLine(config) {
    var i, l, k, k_l, opt, opts, args, name, config_shortNames;

    config['help'] = {
        shortName: 'h',
        help: 'show this help message'
    };

    function printUsage(err) {
        var options, i, l, n, line, option;

        if (err) {
            console.log(err);
            console.log();
        }
        console.log('Usage: ' + path.basename(__filename + ' [options]'));

        options = Object.getOwnPropertyNames(config);
        options.sort();

        l = options.length;
        if (l) {
            console.log();
            console.log("Options:");
            for (i = 0; i < l; ++i) {
                line = '';
                n = options[i];
                option = config[n];
                line += '  --' + n;
                if (option.shortName) {
                    line += ', -' + option.shortName;
                }
                if (option.arg) {
                    line += ' <' + option.arg + '>'
                }
                if (option.help) {
                    line += ' ' + option.help;
                }
                console.log(line);
            }
        }
    }

    function parseOption(name) {
        var optConf;
        if (! config.hasOwnProperty(name)) { throw new Error('No config for ' + name); }
        optConf = config[name];
        if (optConf.arg) {
            if (i === l - 1) {
                console.log('Missing option value: ' + name);
            }
            opts[name] = process.argv[i + 1];
            return 1;
        } else {
            opts[name] = true;
            return 0;
        }
    }

    config_shortNames = {};
    for (i in config) {
        if (config.hasOwnProperty(i)) {
            if (config[i].shortName) {
                config_shortNames[config[i].shortName] = i;
            }
        }
    }

    opts = {};
    args = [];
    for (i = 2, l = process.argv.length; i < l; ++i) {
        opt = process.argv[i];
        if (opt.charAt(0) === '-') {
            if (opt.charAt(1) === '-') {
                // long option name
                name = opt.substring(2);
                if (name === '') {
                    printUsage('Invalid option name: ' + opt);
                    return null;
                }
                if (! config.hasOwnProperty(name)) {
                    printUsage('Unknown option name: ' + name);
                    return null;
                }
                i += parseOption(name);
            } else {
                for (k = 1, k_l = opt.length; k < k_l; ++k) {
                    if (! config_shortNames.hasOwnProperty(opt.charAt(k))) {
                        printUsage('Invalid option name: ' + opt.charAt(k));
                        return null;
                    } else {
                        i += parseOption(config_shortNames[opt.charAt(k)]);
                    }
                }
            }
        } else {
            args.push(opt);
        }
    }

    if (opts.help) {
        printUsage();
        return null;
    }

    return { args: args, opts: opts };
}

function handleData(data) {
    console.log(show.formatData(data));
    if (cmdLine.opts.hasOwnProperty('output')) {
        fs.writeFile(cmdLine.opts.output, JSON.stringify(data), function (err) {
            if (err) {
                console.log('Failed to write to ' + cmdLine.opts.output + ' with error: ' + err);
            } else {
                console.log('Successful write to ' + cmdLine.opts.output);
            }
        });
    }
}

var cmdLine = interpretCmdLine({
    "output" : {
        shortName: 'o',
        arg: 'file',
        help: 'output file'
    },
    "input": {
        shortName: 'i',
        arg: 'file',
        help: 'input file'
    }
});

if (cmdLine.opts.hasOwnProperty('input')) {
    fs.readFile(cmdLine.opts.input, function (err, data) {
        if (err) {
            console.log('Failed to read ' + cmdLine.opts.input + ' with error: ' + err);
        } else {
            try {
                data = JSON.parse(data);
            } catch (e) {
                console.log('Failed to parse file ' + cmdLine.opts.input + ' with error: ' + err);
            }
            handleData(data);
        }
    });
} else {
    handleData(bench.runTests());
}

// interpret command line

// if (process.argv[2] === 'load') {
//     fs.readFile(process.args[3], function (err, data) {
//         if (err) {
//             console.log(err);
//         } else {
//             console.log(formatData(JSON.parse(data)));
//         }
//     });
// } else if (process.argv.length <= 2 || process.argv[2] === 'save') {
//     bench.runTests();
//     console.log(formatData(data));

//     if (process.argv[2] === 'save') {

//     }
// }

